﻿#include <iostream>
#include <boost/asio.hpp>
#include <set>
#include <memory>

using boost::asio::ip::tcp;
using namespace std;
const int max_length = 1024;
typedef std::shared_ptr<tcp::socket> socket_ptr;
std::set<std::shared_ptr<std::thread>> thread_set;

// 服务器处理客户端的读和写 - 线程来执行
void session(socket_ptr sock)
{
    try
    {
        for (;;)
        {
            char data[max_length];
            memset(data, '\0', max_length);
            boost::system::error_code error;
            //size_t lenth = boost::asio::read(sock, boost::asio::buffer(data, max_length), error);
            size_t length = sock->read_some(boost::asio::buffer(data, max_length), error);
            if (error == boost::asio::error::eof) //eof:对端关闭的错误
            {
                cout << "connection closed by peer" << endl;
                break;
            }
            else if (error)
            {
                throw boost::system::system_error(error);
            }
            cout << "receive from " << sock->remote_endpoint().address().to_string() << endl;
            cout << "receive message is " << data << endl;
            //收到的数据回传给客户端
            boost::asio::write(*sock, boost::asio::buffer(data, length));
        }
    }
    catch (exception& e)
    {
        cout << "Exception in thread: " << e.what() << endl;
    }
}

void server(boost::asio::io_context& ioc, unsigned short port_num)
{
    tcp::acceptor a(ioc, tcp::endpoint(tcp::v4(), port_num));
    for (;;)
    {
        socket_ptr socket(new tcp::socket(ioc));
        a.accept(*socket);
        auto t = std::make_shared<std::thread>(session, socket);
        thread_set.insert(t); //避免for过快,导致线程没进行完成函数 - 智能指针就被回收了
    }
}

int main()
{
    try
    {
        cout << "link seccess" << endl;
        boost::asio::io_context ioc;
        server(ioc, 10086);
        for (auto& t : thread_set)
        {
            t->join(); //主线程等待子线程退出之后才退出
        }
    }
    catch (exception& e)
    {
        cout << "Exception in thread: " << e.what() << endl;
    }
    return 0;
}